#ifndef SPHINX_FUNCTION_MANAGER_H
#define SPHINX_FUNCTION_MANAGER_H

/**
 * ReLU激励函数。当x大于0是，返回x；否则返回0。
 * @param x
 * @return
 */
double ReLU(double x);
/**************************************************************************************************/

/**
 * ReLU函数的数组参数的行数和列数
 */
extern int RELU_ARRAY_ROW;
extern int RELU_ARRAY_COLUMN;

/**
 * ReLU激励函数。当x大于0是，返回x；否则返回0。
 * @param x 数组
 * @return
 */
double **ReLUArray(double x[RELU_ARRAY_ROW][RELU_ARRAY_COLUMN]);
/**************************************************************************************************/

/**
 * 求均方误差时，数组参数的行数和列数
 */
extern int MSE_ROW;
extern int MSE_COLUMN;

/**
 * 求均方误差
 * @param trainLabelList
 * @param y
 * @return
 */
double **MeanSquareError(double (*trainLabelList)[1], double (*y)[MSE_COLUMN]);
/**************************************************************************************************/

/**
 * 求row行1列的数组的平均数
 * @param trainLabelList
 * @param row
 * @return
 */
double ReduceMean(double (*meanSquareError)[1], int row);
/**************************************************************************************************/

/**
 * 通过梯度下降算法，计算新的参数列表
 * @param parameterArray 旧的参数列表
 * @param learningRate 学习率
 * @return
 */
double *CalculateNewParameterByGradientDescentAlgorithm(double parameterArray[], int arrayLength, double learningRate);
/**************************************************************************************************/

/**
 * 求损失值。通过求均方误差MSE的方法求损失值
 * @param count
 * @param w2ColumnNumber
 * @param trainLabelList
 * @param y
 * @return
 */
double CalculateLossValue(int count, int w2ColumnNumber, double (*trainLabelList)[1], double (*y)[w2ColumnNumber]);
/**************************************************************************************************/

/**
 * L2正则化（解决过拟合问题）
 * @param w1w2
 * @param rowNumber
 * @param l2RegularizationRate
 * @return
 */
double L2Regularization(double (*w1w2)[1], int rowNumber, double l2RegularizationRate);
/**************************************************************************************************/

/**
 * 训练迭代轮数，从0开始，最多为decaySteps
 */
extern int GLOBAL_STEP = 0;

/**
 * 使用指数衰减法，计算学习率
 * @param learningRate
 * @param decayRate
 * @param globalStep
 * @param decaySteps
 * @return
 */
double CalculateLearningRateByExponentialDecay(double learningRate, double decayRate, int globalStep, int decaySteps);
/**************************************************************************************************/

#endif //SPHINX_FUNCTION_MANAGER_H
